/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import entities.exceptions.MaxFactoryCapacityExceededException;
import entities.exceptions.NotEnoughSupplyException;
import java.awt.Image;

/**
 *
 * @author Mateusz
 * robot transportujący jakiś zasób
 */
public abstract class TransportRobot extends Robot {

    /**
     * current supply transported
     */
    protected Supplies currentSupply;
    /**
     * units transported
     */
    protected int supplyUnits;
    /**
     * maximum robot capacity
     */
    protected int maxCapacity;
    /**
     * cost of creating robot
     */
    protected int buildCost;
    /**
     * factory-mother
     */
    protected Factory factory; 
    
    /**
     * track cost
     */
    protected final int trackCost;
    
    /**
     * Creates transporter robot
     * @param factory       factory associated
     * @param defaultImage  image
     * @param myName        name
     */
    public TransportRobot(Factory factory, Image defaultImage, String myName) {
        super(factory.getAssociatedTile(), defaultImage, myName);

        this.factory = factory;
        this.buildCost = factory.getWorkerCost();
        
        this.cycleRoute = true; // route is cyclic for transport robot - operations are on copies
        
        supplyUnits = 0;
        
        trackCost = 1;
    }

    /**
     * load some units
     * @param units units to load
     */
    protected synchronized void addUnits(int units) {
        this.supplyUnits += units;
    }

    /**
     * unload all units
     * @return unloaded units
     */
    protected synchronized int takeUnits() {
        int units = this.supplyUnits;
        this.supplyUnits = 0;
        return units;
    }

    @Override
    protected void updateProperties() {
        super.updateProperties();
        properties.put("carriedUnits", Integer.toString(supplyUnits));
        properties.put("carriedType", currentSupply.toString());
    }

    /**
     * get fuel for track from factory
     * Put robot sleep if factory hasn't enough supply
     * @param f factory to get fuel from
     */
    protected synchronized void getFuel(Factory f) {
        while (isRunning()) {
            try {
                f.getUnitsFromFactory(trackCost);
                break; // break if route exists
            } catch (NotEnoughSupplyException ex) {
                goSleep();
            }
        }
    }
    
    
    /**
     * load specified units of specified supply
     * Put robot sleep if factory hasn't enough supplies
     * @param f factory
     * @param s supply
     * @param units units
     */
    protected synchronized void load(Factory f, Supplies s, int units) {
        while (isRunning()) {
            try {
                f.getUnitsFromFactory(units, s);
                break; // break if route exists
            } catch (NotEnoughSupplyException ex) {
                goSleep();
            }
        }
        this.supplyUnits = maxCapacity;
        this.currentSupply = s;
    }

    /**
     * unload specified units of specified supply to specified factory.
     * Put robot sleep if factory hasn't enough free space
     * @param f     factory
     * @param s     supply
     * @param units units
     */
    protected synchronized void unload(Factory f, Supplies s, int units) {
        while (isRunning()) {
            try {
                f.addUnits(units, s);
                break; // break if route exists
            } catch (MaxFactoryCapacityExceededException ex) {
                goSleep();
            }
        }
    }
    
    /**
     * @return the buildCost
     */
    public int getBuildCost() {
        return buildCost;
    }
    
    /**
     * 
     * @return factory-mother
     */
    public Factory getFactory() {
        return factory;
    }
    
}

